<template>
  <n-form
    ref="formRef"
    :rules="getFormRules(formList)"
    :model="formData"
    label-placement="left"
    v-bind="formInstanceProps"
  >
    <n-grid :cols="24" :x-gap="24" :y-gap="0" v-bind="gridProps">
      <template v-for="item in formList" :key="item.key">
        <n-form-item-gi
          v-if="!item.hidden"
          :label="item.label"
          :path="item.key"
          :span="item.span ?? 24"
          v-bind="item.originProps"
        >
          <template v-if="item.component === 'NCheckboxGroup'">
            <n-checkbox-group
              v-if="useType !== '查看'"
              v-model:value="formData[item.key]"
              v-bind="getGroupProps(item)"
            >
              <n-checkbox
                v-for="checkItem in item.checkBoxOptions"
                :key="checkItem.value"
                v-bind="checkItem"
              ></n-checkbox>
            </n-checkbox-group>
            <n-ellipsis v-else>{{
              item.transferValue ? item.transferValue(formData[item.key]) : formData[item.key]
            }}</n-ellipsis>
          </template>

          <template v-else-if="item.component === 'NRadioGroup'">
            <n-radio-group
              v-if="useType !== '查看'"
              v-model:value="formData[item.key]"
              v-bind="getGroupProps(item)"
            >
              <template v-if="item.radioType === 'NRadio' || !item.radioType">
                <n-radio
                  v-for="checkItem in item.radioOptions"
                  :key="checkItem.value"
                  v-bind="checkItem"
                ></n-radio>
              </template>
              <n-radio-button
                v-else
                v-for="checkItem in item.radioOptions"
                :key="checkItem.value"
                v-bind="checkItem"
              ></n-radio-button>
            </n-radio-group>
            <n-ellipsis v-else>{{
              item.transferValue ? item.transferValue(formData[item.key]) : formData[item.key]
            }}</n-ellipsis>
          </template>

          <basic-upload
            v-else-if="item.component === 'NUpload'"
            :file-list="formData[item.key]"
            @update:file-list="(val) => updateFileList(item.key, val)"
            :is-show-process="item.isShowProcess"
            v-bind="getGroupProps(item)"
          >
          </basic-upload>

          <template v-else-if="item.component === 'Editor'">
            <basic-editor
              v-if="useType !== '查看'"
              v-model="formData[item.key]"
              style="width: 100%"
              v-bind="getGroupProps(item)"
            ></basic-editor>
            <!-- eslint-disable-next-line vue/no-v-html -->
            <div v-else v-html="formData[item.key]"></div>
          </template>

          <template
            v-else-if="
              item.component === 'NDatePicker' &&
              (item.componentProps as DatePickerProps).valueFormat
            "
          >
            <n-date-picker
              v-if="useType !== '查看'"
              v-model:formatted-value="formData[item.key]"
              clearable
              v-bind="getGroupProps(item)"
            ></n-date-picker>
            <n-ellipsis v-else>{{
              item.transferValue ? item.transferValue(formData[item.key]) : formData[item.key]
            }}</n-ellipsis>
          </template>

          <template
            v-else-if="
              item.component === 'NTimePicker' &&
              (item.componentProps as TimePickerProps).valueFormat
            "
          >
            <n-time-picker
              v-if="useType !== '查看'"
              v-model:formatted-value="formData[item.key]"
              clearable
              v-bind="getGroupProps(item)"
            ></n-time-picker>
            <n-ellipsis v-else>{{
              item.transferValue ? item.transferValue(formData[item.key]) : formData[item.key]
            }}</n-ellipsis>
          </template>

          <template v-else>
            <component
              v-if="useType !== '查看'"
              :is="getComponent(item.component)"
              :placeholder="getDefaultPlaceHolder(item.component, item.label)"
              clearable
              v-bind="getGroupProps(item)"
              v-model:value="formData[item.key]"
            >
            </component>

            <n-ellipsis v-else>{{
              item.transferValue ? item.transferValue(formData[item.key]) : formData[item.key]
            }}</n-ellipsis>
          </template>
        </n-form-item-gi>
      </template>

      <n-form-item-gi :span="24" v-if="!hiddenFooter">
        <n-space justify="end" style="width: 100%">
          <n-button>取消</n-button>
          <n-button type="primary" @click="submit">确定</n-button>
        </n-space>
      </n-form-item-gi>
      <slot name="footer"></slot>
    </n-grid>
  </n-form>
</template>

<script setup lang="ts">
import { PropsForm, BasicFormItemPros, UseType } from './types'
import { getComponent, getDefaultPlaceHolder, getFormRules } from './utils'
import { DatePickerProps, FormInst, FormProps, GridProps, TimePickerProps } from 'naive-ui'

const props = defineProps<{
  propFormData: any
  formList: PropsForm
  useType: UseType // 使用类型
  hiddenFooter?: boolean // 是否隐藏底部
  formInstanceProps?: FormProps // 表单实例属性
  gridProps?: GridProps // 布局属性
}>()

const emit = defineEmits<{
  (e: 'validatePass'): void
  (e: 'updateFormData', val: any): void
}>()

const formRef = ref<FormInst | null>(null)

const formData = computed({
  get() {
    return props.propFormData || {}
  },
  set(val: any) {
    emit('updateFormData', val)
  }
})

const getGroupProps = (item: BasicFormItemPros): any => {
  return item.componentProps
}

function updateFileList(key: string, val: any) {
  formData.value[key] = val
  console.log(formData.value)

  // 更新规则状态
  formRef.value?.validate(
    (errors) => {
      if (errors) {
        console.error(errors)
      }
    },
    (rule) => {
      return rule?.key === key
    }
  )
}

function submit() {
  ;(formRef.value as FormInst).validate((errors) => {
    console.log('验证未通过', formData.value)
    if (!errors) {
      console.log('验证通过', formData.value)
      emit('validatePass')
    }
  })
}
</script>

<style lang="less" scoped></style>
